package nautilus.lab.model;
public class Function {
	//this value is used to hold the address of native Function object
	float[] bufferVertices;
	private int nativeFunction;
	private int errorPos = -1;
	private String function;
	private char[] variables;
	
	//This is vertex buffer
	private float[] buffers = null;
	
	static {
		System.loadLibrary("nmath");
	}
	
	public Function(){
		nativeFunction = 0;
		jniInitilize();
	}
	
	public Function(String str, char[] vars){
		nativeFunction = 0;
		jniInitilize();
		jniSetFunction(str, vars);
	}
	
	public int setFunctionString(String str, char[] vars){
		return jniSetFunction(str, vars);
	}
	
	public int getErrorPosition(){
		return errorPos;
	}
	
	//Return the error value of parsing
	private native void jniInitilize();
	private native int jniSetFunction(String functionString, char[] variables);
	private native String getDerivative();
	public native float f(float[] values);
	private native void jniRelease();
	
	/**
	 *
	 *	@params:
	 *		jarrBoundaries: this array hold the minimum value, maximum value and number of node you want to calculate
	 *		it is a 1-d array, but we must consider it as 3-d array
	 */
	public void genVertices(float[] bounds){
		int numVars = variables.length;
		int d1, d2;
		int i, j;
		float step1, step2, y;
		float[] x = new float[numVars];
		
		
		if(numVars == 1){
			step1 = (bounds[1] - bounds[0])/(bounds[2] - 1);
			buffers = new float[(int)(bounds[2]) * 7];
			x[0] = bounds[0];
			i=0;
			while( x[0] < bounds[1] ){
				y = f(x);
				buffers[i*7] = x[0];
				buffers[i*7 + 1] = y;
				buffers[i*7 + 2] = 0;
				
				//set color of vertex
				buffers[i*7 + 3] = 1.0f;
				buffers[i*7 + 4] = 0;
				buffers[i*7 + 5] = 0;
				buffers[i*7 + 6] = 1;
				
				x[0] += step1;
				i++;
			}
			return;
		}
		
		if(numVars == 2){
			step1 = (bounds[1] - bounds[0])/(bounds[2] - 1);
			d1 = (int)(bounds[2]);
			step2 = (bounds[4] - bounds[3])/(bounds[5] - 1);
			d2 = (int)(bounds[5]);
			buffers = new float[ d1*d2*7 ];
			x[0] = bounds[0];
			i = 0;
			while(x[0] < bounds[1]){ // << d1 step
				x[1] = bounds[3];
				j = 0;
				while(x[1]<bounds[4]){ // d2 step
					y = f(x);
					
					buffers[(i*d1 + j) * 3] = x[0];
					buffers[(i*d1 + j) * 3 + 1] = x[1];
					buffers[(i*d1 + j) * 3 + 2] = y;
					
					//set color of vertex
					buffers[(i*d1 + j)*7 + 3] = 1.0f;
					buffers[(i*d1 + j)*7 + 4] = 0;
					buffers[(i*d1 + j)*7 + 5] = 0;
					buffers[(i*d1 + j)*7 + 6] = 1;
					
					x[1] += step2;
					j++;
				}
				x[0] += step1;
				i++;
			}
			
			return;
		}
	}
	
	public float[] getVertices(){
		return buffers;
	}

	protected void finalize() throws Throwable{
		jniRelease();
		super.finalize();
	}
	
	public void release(){
		jniRelease();
	}
}
